package com.sunchangming.stmdb;

import java.lang.ref.WeakReference;
import java.util.WeakHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 实际上它是一个ReentrantLock的工厂。根据name和object得到一个lock。<br/>
 * 这里的name相当于namespace。同一个namespace下，两个equals的对象将会指向同一个ReentrantLock。<br/>
 * 从这里拿走的锁并不需要回来销毁。但是注意lock和unlock要配对。<br/>
 * 
 * @author Changming
 * 
 */
public class LockManager implements Module {
	// key, value 都是XLock的弱引用。
	private final WeakHashMap<Lockey, WeakReference<Lockey>> locks;
	private final Lock sync;

	public LockManager() {
		locks = new WeakHashMap<Lockey, WeakReference<Lockey>>();
		sync = new ReentrantLock();
	}

	private final Lockey get(Lockey lockey) {
		sync.lock();
		try {
			final WeakReference<Lockey> xlock = locks.get(lockey);
			if (null != xlock) {
				final Lockey l = xlock.get();
				if (null != l)
					return l;
			}
			locks.put(lockey, new WeakReference<Lockey>(lockey));
			lockey.alloc();
			return lockey;
		} finally {
			sync.unlock();
		}
	}

	public final int size() {
		sync.lock();
		try {
			return locks.size();
		} finally {
			sync.unlock();
		}
	}

	private volatile static LockManager instance;

	public static LockManager getInstance() {
		return instance;
	}

	/**
	 * 
	 * @param name
	 *            lock name
	 * @param key
	 *            被保护的对象。注意它的equals、compareTo、hashcode是否被正确实现。
	 * @return
	 */
	public static Lockey get(String name, Object key) {
		return instance.get(new Lockey(name, key));
	}

	@Override
	public void init() throws Exception {
		instance = this;
	}

	@Override
	public void fini() {

	}
}
